package com.oriental.manage.controller.payCount;

import com.oriental.manage.controller.opcif.CountMap;
import com.oriental.manage.core.excelUtils.ExcelTemplateUtil;
import com.oriental.manage.core.fileUtils.FileDownAjax;
import com.oriental.manage.core.fileUtils.HeaderExt;
import com.oriental.manage.core.paging.Pagination;
import com.oriental.manage.core.response.ResponseDTO;
import com.oriental.manage.core.system.Constants;
import com.oriental.manage.core.system.log.OperateLogger;
import com.oriental.manage.core.utils.Bean2MapUtil;
import com.oriental.manage.core.utils.DateUtils;
import com.oriental.manage.pojo.payCount.FailReasonRateReqModel;
import com.oriental.opcif.common.model.RequestModel;
import com.oriental.opcif.common.model.Response;
import com.oriental.opcif.common.model.ResponseModel;
import com.oriental.opcif.product.bizModel.request.boundCount.FailReasonRateReqDto;
import com.oriental.opcif.product.bizModel.response.boudCount.FailDetailRateResDto;
import com.oriental.opcif.product.bizModel.response.boudCount.FailReasonRateResDto;
import com.oriental.opcif.product.facade.bankCount.BankCountFacade;
import com.oriental.paycenter.commons.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.webbuilder.office.excel.config.ExcelWriterConfig;
import org.webbuilder.office.excel.config.Header;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;

/**
 * Desc:
 * Date: 2017/5/3
 * User: Chuch
 * See :
 */
@Slf4j
@Controller
@RequestMapping("cif/agreementFailReport")
public class AgreementFailReportController {
    public static final long DEFAULT_DAY = 92;

    @Autowired(required = false)
    private BankCountFacade bankCountFacade;

    @Autowired
    private Constants constants;
    @Autowired
    private FileDownAjax fileDownAjax;

    @RequestMapping("init")
    @RequiresPermissions("agreementFailReport_search")
    public String init() {
        return "payCount/searchAgreementFailReport";
    }

    @RequestMapping("/search")
    @ResponseBody
    @RequiresPermissions("agreementFailReport_search")
    @OperateLogger(content = "绑卡失败情况分析查询", operationType = OperateLogger.OperationType.R)
    public ResponseDTO<Pagination<FailReasonRateResDto>> queryFailReport(@RequestBody Pagination<FailReasonRateReqDto> query) {
        log.info("绑卡失败情况查询数据:{}", query);
        ResponseDTO<Pagination<FailReasonRateResDto>> responseDTO = new ResponseDTO<>();
        try {
            if (query.getQueryBean() == null) {
                log.error("交易参数不能为空");
                responseDTO.setSuccess(false);
                responseDTO.setMsg("交易参数不能为空");
                return responseDTO;
            }
            if (query.getQueryBean().getStartTime() == null || query.getQueryBean().getEndTime() == null) {
                query.getQueryBean().setEndTime(DateUtil.getCurrent(DateUtil.datePattern));
                query.getQueryBean().setStartTime(DateUtil.format(new Date(System.currentTimeMillis() - DEFAULT_DAY * 24 * 3600 * 1000), DateUtil.datePattern));
            } else {
                long endTime = DateUtil.parse(query.getQueryBean().getEndTime(), DateUtil.datePattern).getTime();
                long startTime = DateUtil.parse(query.getQueryBean().getStartTime(), DateUtil.datePattern).getTime();
                if (endTime > startTime + DEFAULT_DAY * 24 * 3600 * 1000) {
                    log.error("交易统计查询失败，查询时间大于{}", DEFAULT_DAY);
                    responseDTO.setSuccess(false);
                    responseDTO.setMsg("查询时间不能大于" + DEFAULT_DAY + "天");
                    return responseDTO;
                }
            }
            RequestModel<FailReasonRateReqDto> requestModel = new RequestModel<FailReasonRateReqDto>();
            requestModel.setPageNo(query.getPageNum());
            requestModel.setPageSize(query.getPageSize());
            requestModel.setRequest(query.getQueryBean());

            Pagination<FailReasonRateResDto> pagination = new Pagination<>();
            pagination.setPageNum(query.getPageNum());
            pagination.setPageSize(query.getPageSize());

            ResponseModel<FailReasonRateResDto> responseModel = bankCountFacade.queryFailReasonRate(requestModel);
            if (responseModel.getResponseResult()) {
//                if (responseModel.getList().size() > 0) {
                Map<String, List<FailReasonRateResDto>> map = new HashMap<String, List<FailReasonRateResDto>>();
                List<FailReasonRateResDto> list1 = new ArrayList<>();
                for (FailReasonRateResDto f : responseModel.getList()) {
                    f.setFailType(CountMap.queryFailType(f.getFailReason()));
                    if (map.get(f.getFailType()) == null) {
                        list1 = new ArrayList<>();
                        list1.add(f);
                        map.put(f.getFailType(), list1);
                    } else {
                        list1 = map.get(f.getFailType());
                        list1.add(f);
                    }
                    list1 = new ArrayList<>();
                    for (String key : map.keySet()) {
                        list1.addAll(map.get(key));
                    }
                }
                pagination.setRowCount(responseModel.getTotal());
                pagination.setList(list1);
                responseDTO.setSuccess(true);
                responseDTO.setObject(pagination);
                log.info("查询结果", responseModel);
            } else {
                responseDTO.setSuccess(false);
                responseDTO.setMsg(responseModel.getResponseMessage());
            }
        } catch (Exception e) {
            log.error("查询失败", e);
            responseDTO.setSuccess(false);
            responseDTO.setMsg(e.getMessage());
        }
        return responseDTO;
    }


    /**
     * 单条绑卡失败原因明细查询
     */
    @RequestMapping("/failDetail")
    public String toDetail() {
        return "payCount/searchAgreementFailDetail";
    }

    /**
     * 单条绑卡失败原因明细查询
     */
    @RequestMapping("/selectOneReason")
    @ResponseBody
    public ResponseDTO<List<FailDetailRateResDto>> selectOneMsg(FailReasonRateReqDto failReasonRateReqDto) {
        log.info("绑卡失败原因明细查询入参:{}", failReasonRateReqDto);
        ResponseDTO<List<FailDetailRateResDto>> responseDTO = new ResponseDTO<>();
        try {
            Response<List<FailDetailRateResDto>> response = bankCountFacade.queryFailDetailRate(failReasonRateReqDto);
            responseDTO.setCode(response.getResponseCode());
            responseDTO.setMsg(response.getResponseDesc());
            if (response.isSuccess()) {
                responseDTO.setSuccess(true);
                responseDTO.setObject(response.getResult());
            } else {
                responseDTO.setSuccess(false);
            }
        } catch (Exception e) {
            log.error("单条绑卡失败原因明细查询失败：", e);
            responseDTO.setSuccess(false);
            responseDTO.setMsg("查询失败");
        }
        return responseDTO;
    }


    @RequiresPermissions("refund-report_download")
    @RequestMapping("/download")
    public ResponseEntity<byte[]> download(@RequestBody FailReasonRateReqModel pcrm) {
        ResponseEntity<byte[]> responseEntity;
        File tempFile = null;
        try {
            InputStream inputStream = new FileInputStream(constants.getExcelPath() + "/绑卡失败情况分析报表.xlsx");
            tempFile = fileDownAjax.touch("绑卡失败情况分析报表" + DateUtils.now() + ".xlsx");
            RequestModel<FailReasonRateReqDto> requestModel = new RequestModel<FailReasonRateReqDto>();
            FailReasonRateReqDto pc = new FailReasonRateReqDto();
            pc.setStartTime(DateUtil.format(pcrm.getStartTime(), DateUtil.datePattern));
            pc.setEndTime(DateUtil.format(pcrm.getEndTime(), DateUtil.datePattern));
            requestModel.setPageNo(1);
            requestModel.setPageSize(10000);
            requestModel.setRequest(pc);
            ResponseModel<FailReasonRateResDto> responseModel = bankCountFacade.queryFailReasonRate(requestModel);

/*
            if (responseModel.getResponseResult() && responseModel.getList().size() > 0) {
                for (FailReasonRateResDto f : responseModel.getList()) {
                    f.setFailType(CountMap.queryFailType(f.getFailReason()));
                }
            }*/

            //表头
            LinkedList<Header> tHeaders = new LinkedList<>();
            //内容
            List<Object> datas = new ArrayList<>();
            //添加表头
            tHeaders.add(new HeaderExt("序号", "index"));
            tHeaders.add(new HeaderExt("申请开始日期", "startTime"));
            tHeaders.add(new HeaderExt("申请结束日期", "endTime"));
            tHeaders.add(new HeaderExt("类型", "failType"));
            tHeaders.add(new HeaderExt("失败原因", "failReason"));
            tHeaders.add(new HeaderExt("数量", "total"));
            tHeaders.add(new HeaderExt("失败笔数占比", "failReasonRate"));

            int total = 0;
            int i = 1;

            if (responseModel.getResponseResult() && responseModel.getList().size() > 0) {

                Map<String, List<FailReasonRateResDto>> map1 = new HashMap<String, List<FailReasonRateResDto>>();
                List<FailReasonRateResDto> list1 = null;
                for (FailReasonRateResDto failReasonRateResDto : responseModel.getList()) {
                    failReasonRateResDto.setFailType(CountMap.queryFailType(failReasonRateResDto.getFailReason()));

                    if (map1.get(failReasonRateResDto.getFailType()) == null) {
                        list1 = new ArrayList<>();
                        list1.add(failReasonRateResDto);
                        map1.put(failReasonRateResDto.getFailType(), list1);
                    } else {
                        list1 = map1.get(failReasonRateResDto.getFailType());
                        list1.add(failReasonRateResDto);
                    }
                    list1 = new ArrayList<>();
                    for (String key : map1.keySet()) {
                        list1.addAll(map1.get(key));
                    }
                }
                for (FailReasonRateResDto failReasonRateResDto : list1) {
                    Map map = Bean2MapUtil.convertBean(failReasonRateResDto);
                    total += failReasonRateResDto.getTotal();
                    map.put("index", i);
                    i++;
                    datas.add(map);
                }

                /**
                 * 增加一行合计
                 */
                Map map = Bean2MapUtil.convertBean(FailReasonRateResDto.class);
                map.put("failReason", "合计");
                map.put("total", total);
                datas.add(map);
            }

            ExcelWriterConfig config = new ExcelWriterConfig();
            config.setHeaders(tHeaders);
            config.setDatas(datas);
            config.setStartWith(3);

            FileOutputStream outputStream = new FileOutputStream(tempFile);
            ExcelTemplateUtil.write(inputStream, outputStream, config);
            responseEntity = fileDownAjax.getResponseEntity(tempFile);
        } catch (Exception e) {
            log.error("下载失败", e);
            responseEntity = fileDownAjax.getResponseEntityFail();
        } finally {
            fileDownAjax.forceDelete(tempFile);
        }
        return responseEntity;
    }


}
